home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / dl_serie / 065 / tw14w10s / font.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-25  |  10.0 KB  |  412 lines

  1. /*
  2.  * Copyright 1992 Eric R. Smith. All rights reserved.
  3.  * Redistribution is permitted only if the distribution
  4.  * is not for profit, and only if all documentation
  5.  * (including, in particular, the file "copying")
  6.  * is included in the distribution in unmodified form.
  7.  * THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY, NOT
  8.  * EVEN THE IMPLIED WARRANTIES OF MERCHANTIBILITY OR
  9.  * FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN
  10.  * RISK.
  11.  */
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include "xgem.h"
  15. #include "toswin_w.h"
  16. #include "twdefs.h"
  17. #include "twproto.h"
  18.  
  19. char *blank = "";
  20. FONTDESC *fontdesc;
  21.  
  22. static void
  23. blankcopy(dest, src)
  24.     char *dest, *src;
  25. {
  26.     while (*dest && *src) {
  27.         *dest++ = *src++;
  28.     }
  29.     while (*dest)
  30.         *dest++ = ' ';
  31. }
  32.  
  33. void
  34. init_fontdesc()
  35. {
  36.     int i;
  37.     int attrib[10];
  38.     int charw, charh, boxw, boxh;
  39.     char font_name[32];
  40.     int orig_font, orig_size;
  41.     int font_index;
  42.     int prev_size, point_size;
  43.  
  44.     vqt_attributes(vdi_handle, attrib);
  45.     orig_font = attrib[0];
  46.     orig_size = attrib[7];
  47.  
  48.     fontdesc = malloc(gl_numfonts * sizeof(FONTDESC));
  49.     for (i = 0; i < gl_numfonts; i++) {
  50.         font_index = vqt_name(vdi_handle, i+1, font_name);
  51.         if (font_name[BOXLEN]) {    /* FSM font */
  52.             fontdesc[i].isfsm = 1;
  53.         } else {
  54.             fontdesc[i].isfsm = 0;
  55.         }
  56.         font_name[BOXLEN] = 0;
  57.         if (!strcmp(font_name, "6x6 system font"))
  58.             strcpy(font_name, "System Font");
  59.         strcpy(fontdesc[i].name, font_name);
  60.         fontdesc[i].fontidx = font_index;
  61.         fontdesc[i].points = 0L;
  62.         vst_font(vdi_handle, font_index);
  63.         point_size = 32;
  64.         fontdesc[i].num_points = 0;
  65.         for(;;) {
  66.             prev_size = point_size - 1;
  67.             point_size = vst_point(vdi_handle, prev_size,
  68.                 &charw, &charh, &boxw, &boxh);
  69.             if (point_size > prev_size) break;
  70.             fontdesc[i].points |= (1L << (long)point_size);
  71.             fontdesc[i].num_points++;
  72.         }
  73.     }
  74.     vst_font(vdi_handle, orig_font);
  75.     vst_height(vdi_handle, orig_size, &charw, &charh, &boxw, &boxh);
  76. }
  77.  
  78. #define NUMLINES 8
  79. #define FNTLIN      FNTLIN1
  80. #define FNTLINLAST  (FNTLIN+NUMLINES-1)
  81. #define SIZLIN      SIZLIN1
  82. #define SIZLINLAST  (SIZLIN+NUMLINES-1)
  83.  
  84. void
  85. set_fontbox(off, maxfntoff, draw)
  86.     int off, maxfntoff, draw;
  87. {
  88.     int i;
  89.     int n = FNTLIN;
  90.     int fntoff = off;
  91.  
  92.     for (i = 0; i < gl_numfonts; i++) {
  93.         if (off == 0) {
  94.             blankcopy((char *)fontdial[n].ob_spec,
  95.                 fontdesc[i].name);
  96.             fontdial[n].ob_flags |= TOUCHEXIT;
  97.             fontdial[n].ob_state = NORMAL;
  98.             if (++n > FNTLINLAST) break;
  99.         } else
  100.             --off;
  101.     }
  102.  
  103.     while (n <= FNTLINLAST) {
  104.         blankcopy((char *)fontdial[n].ob_spec, blank);
  105.         fontdial[n].ob_flags &= ~TOUCHEXIT;
  106.         fontdial[n].ob_state = NORMAL;
  107.         n++;
  108.     }
  109.  
  110.     if (gl_numfonts <= NUMLINES) {
  111.         fontdial[FNTSLIDE].ob_y = 0;
  112.         fontdial[FNTSLIDE].ob_height = fontdial[FNTSLIBX].ob_height;
  113.         fontdial[FNTSLIDE].ob_flags &= ~TOUCHEXIT;
  114.         fontdial[FNTSLIBX].ob_flags &= ~TOUCHEXIT;
  115.         fontdial[FNTUPARR].ob_flags &= ~TOUCHEXIT;
  116.         fontdial[FNTDNARR].ob_flags &= ~TOUCHEXIT;
  117.     } else {
  118.         i = (fontdial[FNTSLIBX].ob_height * NUMLINES) / gl_numfonts;
  119.         if (i <= 0) i = 1;
  120.         fontdial[FNTSLIDE].ob_y =
  121.             (fontdial[FNTSLIBX].ob_height * fntoff) / gl_numfonts;
  122.         fontdial[FNTSLIDE].ob_height = i;
  123.         fontdial[FNTSLIDE].ob_flags |= TOUCHEXIT;
  124.         fontdial[FNTSLIBX].ob_flags |= TOUCHEXIT;
  125.         fontdial[FNTUPARR].ob_flags |= TOUCHEXIT;
  126.         fontdial[FNTDNARR].ob_flags |= TOUCHEXIT;
  127.     }
  128.     if (draw) {
  129.         objc_draw(fontdial, FNTSLIBX, 1, xdesk, ydesk, wdesk, hdesk);
  130.         objc_draw(fontdial, FONTBOX, 1, xdesk, ydesk, wdesk, hdesk);
  131.     }
  132. }
  133.  
  134. static char *pointstr(d)
  135.     int d;
  136. {
  137.     static char foo[16];
  138.     char *s;
  139.  
  140.     s = valdec(d);
  141.     if (s[0] == '0') {
  142.         s[0] = ' ';
  143.         if (s[1] == '0') s[1] = ' ';
  144.     }
  145.     strcpy(foo, s);
  146.     strcat(foo, " points");
  147.     return foo;
  148. }
  149.  
  150. void
  151. set_sizebox(f, off, draw)
  152.     FONTDESC *f;
  153.     int off, draw;
  154. {
  155.     int i, j;
  156.     int n = SIZLIN;
  157.     int sizoff = off;
  158.  
  159.     for (j = 0; j < 32; j++) {
  160.         if (f->points & (1L << (long)j)) {
  161.             if (off == 0) {
  162.                 blankcopy((char *)fontdial[n].ob_spec,
  163.                      pointstr(j));
  164.                 fontdial[n].ob_flags |= TOUCHEXIT;
  165.                 fontdial[n].ob_state = NORMAL;
  166.                 if (++n > SIZLINLAST) break;
  167.             } else {
  168.                 --off;
  169.             }
  170.         }
  171.     }
  172.     while (n <= SIZLINLAST) {
  173.         blankcopy((char *)fontdial[n].ob_spec, blank);
  174.         fontdial[n].ob_flags &= ~TOUCHEXIT;
  175.         fontdial[n].ob_state = NORMAL;
  176.         n++;
  177.     }
  178.     if (f->num_points <= NUMLINES) {
  179.         fontdial[SIZSLIDE].ob_y = 0;
  180.         fontdial[SIZSLIDE].ob_height = fontdial[SIZSLIBX].ob_height;
  181.         fontdial[SIZSLIBX].ob_flags &= ~TOUCHEXIT;
  182.         fontdial[SIZSLIDE].ob_flags &= ~TOUCHEXIT;
  183.         fontdial[SIZUPARR].ob_flags &= ~TOUCHEXIT;
  184.         fontdial[SIZDNARR].ob_flags &= ~TOUCHEXIT;
  185.     } else {
  186.         i = (fontdial[SIZSLIBX].ob_height * NUMLINES) / gl_numfonts;
  187.         if (i <= 0) i = 1;
  188.         fontdial[SIZSLIDE].ob_y =
  189.             (fontdial[SIZSLIBX].ob_height * sizoff) / gl_numfonts;
  190.         fontdial[SIZSLIDE].ob_height = i;
  191.         fontdial[SIZSLIDE].ob_flags |= TOUCHEXIT;
  192.         fontdial[SIZSLIBX].ob_flags |= TOUCHEXIT;
  193.         fontdial[SIZUPARR].ob_flags |= TOUCHEXIT;
  194.         fontdial[SIZDNARR].ob_flags |= TOUCHEXIT;
  195.     }
  196.     if (draw) {
  197.         objc_draw(fontdial, SIZSLIBX, 1, xdesk, ydesk, wdesk, hdesk);
  198.         objc_draw(fontdial, SIZEBOX, 1, xdesk, ydesk, wdesk, hdesk);
  199.     }
  200. }
  201.  
  202. /*
  203.  * slide a box around, and return the new position for it
  204.  */
  205.  
  206. int
  207. slide(tree, box, slider, maxoff)
  208.     OBJECT *tree;
  209.     int box, slider, maxoff;
  210. {
  211.     int totsiz = maxoff + NUMLINES;
  212.     long r;
  213.  
  214.     r = graf_slidebox(tree, box, slider, 1);
  215.     /* r is now scaled from 0-1000 */
  216.     r = (totsiz * r) / 1000 - (NUMLINES/2);
  217.     if (r < 0) r = 0;
  218.     if (r > maxoff) r = maxoff;
  219.     return r;
  220. }
  221.  
  222. /*
  223.  * respond to a click in the "page" area of a slider box
  224.  */
  225.  
  226. int
  227. page(tree, box, slider, off, maxoff)
  228.     OBJECT *tree;
  229.     int box, slider, off, maxoff;
  230. {
  231.     int x1, y1, x2, y2;
  232.     int x, y, dummy;
  233.  
  234.     graf_mkstate(&x, &y, &dummy, &dummy);
  235.  
  236. /* mouse sanity check */
  237.     objc_offset(tree, box, &x1, &y1);
  238.     if (x < x1 || x > x + tree[box].ob_width || y < y1 ||
  239.         y > y + tree[box].ob_height) return off;
  240.  
  241. /* check first rectangle */
  242.     objc_offset(tree, slider, &x2, &y2);
  243.     if (y >= y1 && y < y2) {        /* yes, it's a page up */
  244.         off -= NUMLINES;
  245.         if (off < 0) off = 0;
  246.         return off;
  247.     }
  248. /* OK, check second rectangle */
  249.     y1 += tree[box].ob_height;
  250.     y2 += tree[slider].ob_height;
  251.     if (y > y2 && y <= y1) {
  252.         off += NUMLINES;
  253.         if (off > maxoff) off = maxoff;
  254.     }
  255.     return off;
  256. }
  257.  
  258. #define update_sizebox() objc_draw(fontdial, SIZNMBOX, 3, x, y, w, h);
  259.  
  260. int
  261. get_font(font, size)
  262.     int *font, *size;
  263. {
  264.     int i, x, y, w, h;
  265.     int ret;
  266.     int doubleclick;
  267.     int oldfnt = -1;
  268.     int fntoff, sizoff;
  269.     int oldsiz = -1;
  270.     FONTDESC *f;
  271.     int maxfntoff, maxsizoff;
  272.     char *sizestr;
  273.     TEDINFO *ted;
  274.  
  275.     fntoff = sizoff = maxsizoff = 0;
  276.  
  277.     ted = (TEDINFO *)fontdial[SIZNMPTS].ob_spec;
  278.     sizestr = (char *)ted->te_ptext;
  279.  
  280.     maxfntoff = gl_numfonts - NUMLINES;
  281.  
  282. /* see if we can find the already existing font and size */
  283.     f = 0;
  284.     for (i = 0; i < gl_numfonts; i++) {
  285.         if (fontdesc[i].fontidx == *font) {
  286.             f = &fontdesc[i];
  287.             break;
  288.         }
  289.     }
  290.     if (f) {
  291.         blankcopy((char *)fontdial[FNTNMSTR].ob_spec, f->name);
  292.         maxsizoff = f->num_points - NUMLINES;
  293.         set_sizebox(f, 0, 0);
  294.     } else {
  295.         blankcopy((char *)fontdial[FNTNMSTR].ob_spec, blank);
  296.         for (i = SIZLIN; i <= SIZLINLAST; i++) {
  297.             blankcopy((char *)fontdial[i].ob_spec, blank);
  298.             fontdial[i].ob_flags &= ~TOUCHEXIT;
  299.         }
  300.         fontdial[SIZSLIDE].ob_height = fontdial[FNTSLIBX].ob_height;
  301.         fontdial[SIZSLIDE].ob_flags &= ~TOUCHEXIT;
  302.         fontdial[SIZUPARR].ob_flags &= ~TOUCHEXIT;
  303.         fontdial[SIZDNARR].ob_flags &= ~TOUCHEXIT;
  304.     }
  305.  
  306.     if (f && (f->points & (1L << (long)*size))) {
  307.         char *s = pointstr(*size);
  308.         sizestr[0] = s[1];
  309.         sizestr[1] = s[2];
  310.     } else {
  311.         sizestr[0] = sizestr[1] = ' ';
  312.     }
  313.  
  314.     form_center(fontdial, &x, &y, &w, &h);
  315.     set_fontbox(fntoff, maxfntoff, 0);
  316.  
  317.     wind_update(1);
  318.     form_dial(FMD_START, 0, 0, 32, 32, x, y, w, h);
  319.     if (win_flourishes)
  320.         form_dial(FMD_GROW, 0, 0, 32, 32, x, y, w, h);
  321.     objc_draw(fontdial, 0, 5, x, y, w, h);
  322.  
  323.     for(;;) {
  324.         doubleclick = 0;
  325.         ret = form_do(fontdial, SIZNMPTS);
  326.         if (ret & 0x8000) {
  327.             doubleclick = 1;
  328.             ret &= 0x7fff;
  329.         }
  330.         if (ret == FNTOK || ret == FNTCAN) {
  331.             objc_change(fontdial, ret, 0, x, y, w, h, NONE, 0);
  332.             break;
  333.         }
  334.         else if (ret >= FNTLIN && ret <= FNTLINLAST) {
  335.             if (oldfnt >= 0) {
  336.                 objc_change(fontdial, oldfnt, 0, x, y, w, h,
  337.                         NONE, 1);
  338.             }
  339.             if (ret != oldfnt) {
  340.                 sizestr[0] = sizestr[1] = ' ';
  341.                 update_sizebox();
  342.             }
  343.             oldfnt = ret;
  344.             objc_change(fontdial, ret, 0, x, y, w, h, SELECTED, 1);
  345.             f = &fontdesc[ret-FNTLIN+fntoff];
  346.             blankcopy((char *)fontdial[FNTNMSTR].ob_spec, f->name);
  347.             objc_draw(fontdial, FNTNMBOX, 1, x, y, w, h);
  348.             sizoff = 0; oldsiz = -1;
  349.             maxsizoff = f->num_points - NUMLINES;
  350.             set_sizebox(f, sizoff, 1);
  351.         }
  352.         else if (ret >= SIZLIN && ret <= SIZLINLAST) {
  353.             if (oldsiz >= 0) {
  354.                 objc_change(fontdial, oldsiz, 0, x, y, w, h,
  355.                     NONE, 1);
  356.             }
  357.             oldsiz = ret;
  358.             objc_change(fontdial, ret, 0, x, y, w, h, SELECTED, 1);
  359.             sizestr[0] = ((char *)fontdial[ret].ob_spec)[1];
  360.             sizestr[1] = ((char *)fontdial[ret].ob_spec)[2];
  361.             update_sizebox();
  362.             if (doubleclick) break;
  363.         }
  364.         else if (ret == FNTUPARR && fntoff > 0) {
  365.             fntoff--;
  366.             set_fontbox(fntoff, maxfntoff, 1);
  367.         } else if (ret == FNTDNARR && fntoff < maxfntoff) {
  368.             fntoff++;
  369.             set_fontbox(fntoff, maxfntoff, 1);
  370.         } else if (ret == SIZUPARR && sizoff > 0) {
  371.             sizoff--;
  372.             set_sizebox(f, sizoff, 1);
  373.         } else if (ret == SIZDNARR && sizoff < maxsizoff) {
  374.             sizoff++;
  375.             set_sizebox(f, sizoff, 1);
  376.         } else if (ret == FNTSLIDE) {
  377.             fntoff = slide(fontdial, FNTSLIBX, FNTSLIDE, maxfntoff);
  378.             set_fontbox(fntoff, maxfntoff, 1);
  379.         } else if (ret == SIZSLIDE) {
  380.             sizoff = slide(fontdial, SIZSLIBX, SIZSLIDE, maxsizoff);
  381.             set_sizebox(f, sizoff, 1);
  382.         } else if (ret == SIZSLIBX) {
  383.             sizoff = page(fontdial, SIZSLIBX, SIZSLIDE, sizoff, 
  384.                     maxsizoff);
  385.             set_sizebox(f, sizoff, 1);
  386.         } else if (ret == FNTSLIBX) {
  387.             fntoff = page(fontdial, FNTSLIBX, FNTSLIDE, fntoff,
  388.                     maxfntoff);
  389.             set_fontbox(fntoff, maxfntoff, 1);
  390.         }
  391.     }
  392.     if (win_flourishes)
  393.         form_dial(FMD_SHRINK, 0, 0, 32, 32, x, y, w, h);
  394.     form_dial(FMD_FINISH, 0, 0, 32, 32, x, y, w, h);
  395.     wind_update(0);
  396.  
  397.     if (ret == FNTCAN || !f)
  398.         return FAIL;
  399.  
  400.     while (*sizestr == ' ') sizestr++;
  401.     i = (*sizestr - '0'); sizestr++;
  402.     if (i < 0 || i > 9) return FAIL;
  403.     if (*sizestr >= '0' && *sizestr <= '9') {
  404.         i = 10 * i + (*sizestr - '0');
  405.     }
  406.  
  407.     *font = f->fontidx;
  408.     *size = i;
  409.  
  410.     return OK;
  411. }
  412.